/*
 * Copyright (C) 2007-2010 Crise, crise<at>mail.berlios.de
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifndef MP_PLUGIN_H
#define MP_PLUGIN_H

#include "version.h"
#include <Singleton.h>

#include <map>

using namespace dcpp; 

class MPPlugin : public Singleton<MPPlugin>
{
public:
	MPPlugin() : mediaBand(-1), hWndRebar(NULL), mainWnd(NULL) { }
	~MPPlugin() { };

	Bool onLoad(DCCorePtr core, bool install);
	Bool onUnload();
	Bool onConfig(HWND hWnd);

	Bool processCommand(dcptr_t pObject, CommandDataPtr cmd, DCHubPtr hub, bool isPrivate);
	bool parseCommand(const char* cmd, const char* param, string& result, bool& status);

	// Event functions
	static Bool DCAPI onChatCommand(dcptr_t pObject, dcptr_t pData, void* pCommon, Bool* /*bBreak*/) { return MPPlugin::getInstance()->processCommand(pObject, (CommandDataPtr)pData, (DCHubPtr)pCommon, false); }
	static Bool DCAPI onChatCommandPM(dcptr_t pObject, dcptr_t pData, void* pCommon, Bool* /*bBreak*/) { return MPPlugin::getInstance()->processCommand(pObject, (CommandDataPtr)pData, (DCHubPtr)pCommon, true); }
	static Bool DCAPI onUiCreated(dcptr_t pObject, dcptr_t /*pData*/, void* /*pCommon*/, Bool* /*bBreak*/) { return MPPlugin::getInstance()->setAppWindow((HWND)pObject); }

	// Window message handlers
	void onWindowActivated(HWND hWnd);
	void onWindowNotify(LPARAM lParam);

	HWND getAppWindow() const { return mainWnd; }
	Bool setAppWindow(HWND hWnd) { mainWnd = hWnd; return True; }

	bool isBarAvailable() { return !mainWnd || hWndRebar; }

	// Settings helpers
	string getOption(const char* name) {
		auto value = (ConfigStrPtr)config->get_cfg(PLUGIN_GUID, name, CFG_TYPE_STRING);
		string str(value->value);
		config->release((ConfigValuePtr)value);
		return str;
	}

	bool getBoolOption(const char* name) {
		auto value = (ConfigIntPtr)config->get_cfg(PLUGIN_GUID, name, CFG_TYPE_INT);
		int32_t num = value->value;
		config->release((ConfigValuePtr)value);
		return (num != 0);
	}

	void setOption(const char* name, const char* value) {
		ConfigStr val;
		memset(&val, 0, sizeof(ConfigStr));

		val.type = CFG_TYPE_STRING;
		val.value = value;
		config->set_cfg(PLUGIN_GUID, name, (ConfigValuePtr)&val);
	}

	void setOption(const char* name, const string& value) { setOption(name, value.c_str()); }
	void setOption(const char* name, bool state) { setOption(name, state ? "1" : "0"); }

	// String conversion helpers
	static wstring DCAPI toWide(string str) {
		wstring res;
		if(str.empty())
			return res;
		auto n = str.size();
		res.resize(n);
		res.resize(utils->utf8_to_wcs(&res[0], &str[0], n));
		if(res.size() > n) {
			utils->utf8_to_wcs(&res[0], &str[0], res.size());
		}
		return res;
	}

	static string DCAPI fromWide(wstring str) {
		string res;
		if(str.empty())
			return res;
		auto n = str.size() * 3 / 2;
		res.resize(n);
		res.resize(utils->wcs_to_utf8(&res[0], &str[0], n));
		if(res.size() > n) {
			utils->wcs_to_utf8(&res[0], &str[0], res.size());
		}
		return res;
	}

	DCCorePtr dcpp;
	DCHooksPtr hooks;
	DCConfigPtr config;

	static DCUtilsPtr utils;

private:
	CToolBarCtrl ctrlMediaBar;
	CImageList mediabarImages;
	HWND hWndRebar, mainWnd;
	int mediaBand;

	map<string, subsHandle> events;

	friend class Singleton<MPPlugin>;
	static MPPlugin* instance;
};

#endif // MP_PLUGIN_H